package com.xiejr.actuator.socket.config;

import com.xiejr.actuator.socket.Topic;
import com.xiejr.actuator.socket.proxy.TopicProxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.lang.reflect.Proxy;

/**
 * @program: socket-actuator-spring-boot-starter
 * @description: 主题式socket工厂bean
 * @author: xjr
 * @create: 2020-07-13 15:10
 **/
public class TopicSocketFactoryBean implements FactoryBean<Topic>, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private Class<Topic> targetClass;

    private String beanName;

    @Override
    public Topic getObject() throws Exception {
        return getProxyBean();
    }

    @Override
    public Class<?> getObjectType() {
        return targetClass;
    }

    /**
     *
     * jdk动态代理
     * @author xiejiarong
     * @date 2020年05月16日 10:47
     * @throws Exception
     */
    public  Topic getProxyBean(){
        AutowireCapableBeanFactory autowireCapableBeanFactory=this.applicationContext.getAutowireCapableBeanFactory();
        Topic topic=autowireCapableBeanFactory.createBean(targetClass);
        TopicProxy proxy=autowireCapableBeanFactory.createBean(TopicProxy.class);
        proxy.setTopic(topic);
        proxy.setBeanName(beanName);
        return (Topic) Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{Topic.class},proxy);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }

    public TopicSocketFactoryBean(Class<Topic> targetClass,String beanName){
        this.targetClass=targetClass;
        this.beanName=beanName;
    }
}
